import $ from '../fn/data_type'
import $wx from '../wx'
import Regex from './regex'
// 加错误标识
const addError =  function(row, msg, showMsg) {
    row['error'] = true
    row['errorMsg'] = msg
    if(showMsg!=false){
        $wx.msg.info(msg)
    }
    console.error(row.name, msg)
}
// 字符串判断
const stringFn = function(rules, currentValue, row, showMsg){
    const { value, msg } = Regex.test(rules, currentValue)
    if(!value){
        addError(row, msg, showMsg)
        return true
    }
}
// 对象判断
const objectFn = function(rules, currentValue, row, showMsg){
    let { max, min, len, reg, attr } = rules
        const keys = Object.keys(rules)
        if( keys.length ===0 ) return
        let rule
        let num
        if(keys.includes('max')){
            rule = 'max'
            num = max
        }else if(keys.includes('min')){
            rule = 'min'
            num = min
        }else if(keys.includes('len')){
            rule = 'len'
            num = len
        }
        if( rule ){
            let { value, msg } = Regex.test(rule, currentValue, num)
            if(!value){
                msg = rules.msg ?? row.label + msg
                addError(row, msg, showMsg)
                return true
            }
        }
        if($.isString(rules)){
            if(stringFn(rules, currentValue, row))  return true
        }
        // reg 管理
        if($.isString(reg)){
            let { value, msg } = Regex.test(reg, currentValue)
            if($.isBoolean(value)){
                if(!value){
                    msg = rules.msg ?? msg
                    addError( row, msg, showMsg)
                    return true
                }
            }else{
                reg = new RegExp(reg, attr)
                const bool = reg.test(currentValue)
                if(!bool){
                    msg = rules.msg
                    addError(row, msg, showMsg)
                    return true
                }
            }
        }else if($.isFunction(reg)){
            const r = reg(currentValue)
            let bool, msg
            if($.isObject(r)){
                bool = r.bool
                msg = r.msg || rules.msg
            }else{
                bool = r
                msg = rules.msg
            }
            if(!bool){
                addError(row, msg, showMsg)
                return true
            }
        }
}
// 自动验证
const changeRules = ({rules, name, label}) => {
    if(!rules){
        if( name.includes('phone')  ) rules = [{len:11, msg: (label||'手机号') + '为 11 位'}, 'phone']
        if( name.includes('email') ) rules = 'email'
        if( name === 'age' ) rules =  [{min:0, msg: (label||'年龄') + '必须大于 0'}, {max:125, msg: (label||'年龄') + '必须小于 125'}]
        if( name.includes('password') ) rules = 'password'
        if( name.includes('idcard') ) rules = 'idcard'
        if( name.includes('bank_card') ) rules = 'bank_card'
    }
    return rules
}
// 表单提交时验证
const submitValidate = function(data, submitValue, showMsg){
    let index = 0
    const length = data.length
    for(let i=0; i<length; i++){
        const row = data[i]
        let { r, max, min, maxLen, minLen, len, label, name, rules} = row
        const currentValue = submitValue?.[name]
        // 空
        if(r && $.isEmpty(currentValue) ){
            const msg = label + '必填'
            addError(row, msg, showMsg)
            break
        }
        if(!$.isEmpty(currentValue)) rules = changeRules(row)
        // 最大值
        if(max && max < currentValue ){
            const msg = `${label}最大值为 ${max}`
            addError(row, msg, showMsg)
            break
        }
        // 最小值
        if(min && min > currentValue ){
            const msg = `${label}最小值为 ${min}`
            addError(row, msg, showMsg)
            break
        }
        // 最大长度
        if(maxLen && maxLen < currentValue.length ){
            const msg = `${label}最长为 ${maxLen} 个字符`
            addError(row, msg, showMsg)
            break
        }
        // 最小长度
        if(minLen && minLen > currentValue.length ){
            const msg = `${label}最小为 ${minLen} 个字符`
            addError(row, msg, showMsg)
            break
        }
        // 等于长度
        if(len && len !== currentValue.length ){
            const msg = `${label}长度为 ${len}`
            addError(row, msg, showMsg)
            break
        }
        //
        if( $.hasArray( rules ) ){ // 数组
            let rx = 0
            const len = rules.length
            for(let k=0; k<len; k++){
                if(objectFn(rules[k], currentValue, row, showMsg)) break
                rx ++
            }
            if(rx !== len) break
        }else if($.isString( rules )){
            if(stringFn(rules, currentValue, row, showMsg)) break
        }else if($.hasObject( rules )){
            if(objectFn(rules, currentValue, row, showMsg)) break
        }else if($.isFunction( rules )){
            const {bool, msg} = rules(v)
            if(!bool) { addError(row, msg, showMsg); break }
        }
        index++
        delete row['error']
        delete row['errorMsg']
    }
    
    return index === length
}
// 值变化时验证
const changeValidate = function(row,currentValue){
    const showMsg = false
    let { r, max, min, maxLen, minLen, len, label, name, rules} = row
    // 空
    if(r && $.isEmpty(currentValue) ){
        const msg = label + '必填'
        addError(row, msg, showMsg)
        return false
    }
    if(!$.isEmpty(currentValue)) rules = changeRules(row)
    // 最大值
    if(max && max < currentValue ){
        const msg = `${label}最大值为 ${max}`
        addError(row, msg, showMsg)
        return false
    }
    // 最小值
    if(min && min > currentValue ){
        const msg = `${label}最小值为 ${min}`
        addError(row, msg, showMsg)
        return false
    }
    // 最大长度
    if(maxLen && maxLen < currentValue.length ){
        const msg = `${label}最长为 ${maxLen} 个字符`
        addError(row, msg, showMsg)
        return false
    }
    // 最小长度
    if(minLen && minLen > currentValue.length ){
        const msg = `${label}最小为 ${minLen} 个字符`
        addError(row, msg, showMsg)
        return false
    }
    // 等于长度
    if(len && len !== currentValue.length ){
        const msg = `${label}长度为 ${len}`
        addError(row, msg, showMsg)
        return false
    }
    //
    if( $.hasArray( rules ) ){
        let rx = 0
        const len = rules.length
        for(let k=0; k<len; k++){
            if(objectFn(rules[k], currentValue, row, showMsg)) return false
            rx ++
        }
        if(rx !== len) return false
    }else if($.isString( rules )){
        if(stringFn(rules, currentValue, row, showMsg)) return false
    }else if($.hasObject( rules )){
        if(objectFn(rules, currentValue, row, showMsg)) return false
    }else if($.isFunction( rules )){
        const {bool, msg} = rules(v)
        if(!bool) { addError(row, msg, showMsg); return false }
    }
    row['error'] = false
    delete row['errorMsg']
    return true
}
export default { submitValidate, changeValidate, submitValidate }
